﻿namespace PipelineMode;
/// <summary>
/// 管道设计模式
/// </summary>
public class PipelineModeClass
{
    public static async Task testMain()
    {
        var builder = new ApplicationBuilder();

        builder.Use(async (context, next) =>
        {
            Console.WriteLine("Pipeline--111111");
            await next();
            Console.WriteLine("Pipeline--222222");
        });

        builder.Use(async (context, next) =>
        {
            Console.WriteLine("Pipeline--333333");
            await next();
            Console.WriteLine("Pipeline--444444");
        });

        builder.Run(context =>
        {
            Console.WriteLine("操作业务逻辑额");
            return Task.CompletedTask;
        });
        var app = builder.Build();

        await app(new HttpContext());
    }
}

public class HttpContext
{
    public string Request { get; }
    public string response { get; }
}

public delegate Task RequestDelegate(HttpContext context);

public class ApplicationBuilder
{
    private List<Func<RequestDelegate, RequestDelegate>> _componments = new();

    /// <summary>
    /// 主要
    /// </summary>
    /// <param name="middleware"></param>
    public void Use(Func<RequestDelegate, RequestDelegate> middleware)
    {
        _componments.Add(middleware);
    }

    /// <summary>
    /// 扩展一
    /// </summary>
    /// <param name="middleware"></param>
    public void Use(Func<HttpContext, Func<Task>, Task> middleware)
    {
        _componments.Add(next =>
        {
            return async context =>
            {
                await middleware(context, () => next(context));
            };
        });
    }

    /// <summary>
    /// 扩展二
    /// </summary>
    /// <param name="middleware"></param>
    public void Run(Func<HttpContext, Task> middleware)
    {
        _componments.Add(next =>
        {
            return async context =>
            {
                await middleware(context);
            };
        });
    }

    public RequestDelegate Build()
    {
        RequestDelegate app = context =>
        {
            throw new InvalidOperationException("不合法的管道");
        };
        for (int i = _componments.Count - 1; i > -1; i--)
        {
            app = _componments[i](app);
        }
        return app;
    }
}